package com.linked.universal.common;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.linked.universal.utils.IDUtils;
import com.linked.universal.utils.LinkedTimeUtils;
import lombok.Data;
import org.slf4j.MDC;

import java.io.Serializable;


/**
 * @author :dbq
 * @date : 2023/3/10 8:12
 * @description : 统一响应结果类
 */

@Data
public class LinkedResult implements Serializable {

    private static final long serialVersionUID = 1L;

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
            .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
            .setSerializationInclusion(JsonInclude.Include.NON_NULL);

    /**
     * http响应码
     */
    String code;

    /**
     * 错误码
     */
    String errorCode;

    /**
     * 业务调用是否成功
     */
    boolean success;

    /**
     * 提示信息
     */
    String message;

    /**
     * 数据存储
     */
    Object data;

    /**
     * 数据存储
     */
    final String timestamp;

    /**
     * 请求id
     */
    final String requestId;

    /**
     * 追踪id
     */
    final String traceId;

    LinkedResult() {
        this.timestamp = LinkedTimeUtils.now();
        this.requestId = IDUtils.getUUID("REQ");
        this.traceId = MDC.get("traceId");
    }

    /**
     * @return 接口统一返回类
     * @Deprecated 简单的成功返回方法
     */
    public static LinkedResult Success() {
        return Complete(LinkedCEM.SUCCESS);
    }

    /**
     * @param data 返回数据
     * @return 接口统一返回类
     * @Deprecated 带数据的成功返回方法
     */
    public static LinkedResult Success(Object data) {
        LinkedResult lr = Complete(LinkedCEM.SUCCESS, data);
        return lr;
    }

    /**
     * @param msg  提示信息
     * @param data 返回数据
     * @return 接口统一返回类
     * @Deprecated 自定义提示信息，并带数据的接口成功返回方法
     */
    public static LinkedResult Success(String msg, Object data) {
        LinkedResult lr = Complete(LinkedCEM.SUCCESS, data);
        lr.message = msg;
        return lr;
    }

    @Deprecated
    public static LinkedResult OK(boolean ifSuccess, String msg) {
        LinkedResult lr = new LinkedResult();
        lr.code = String.valueOf(LinkedCEM.SUCCESS.getCode());
        lr.success = ifSuccess;
        lr.message = msg;
        return lr;
    }

    @Deprecated
    public static LinkedResult OK(boolean ifSuccess, LinkedCEM cem) {
        LinkedResult lr = Complete(cem);
        lr.success = ifSuccess;
        return lr;
    }

    @Deprecated
    public static LinkedResult OK(boolean ifSuccess, String msg, Object data) {
        LinkedResult lr = new LinkedResult();
        lr.code = LinkedCEM.SUCCESS.getCode().toString();
        lr.success = ifSuccess;
        lr.message = msg;
        lr.data = data;
        return lr;
    }

    @Deprecated
    public static LinkedResult OK(String code, boolean ifSuccess, String msg, Object data) {
        LinkedResult lr = new LinkedResult();
        lr.code = code;
        lr.success = ifSuccess;
        lr.message = msg;
        lr.data = data;
        return lr;
    }

    public static LinkedResult Error() {
        return Complete(LinkedCEM.ERROR_MESSAGE);
    }

    public static LinkedResult Error(String msg) {
        LinkedResult lr = Complete(LinkedCEM.ERROR_MESSAGE);
        lr.message = msg;
        return lr;
    }

    /**
     * @param msg  提示信息
     * @param data 返回数据
     * @return 接口统一返回类
     * @Deprecated 针对参数错误的情况
     */
    public static LinkedResult Error(String msg, Object data) {
        LinkedResult lr = Complete(LinkedCEM.ERROR_MESSAGE, data);
        lr.message = msg;
        return lr;
    }

    /**
     * 业务错误码，不再由code字段,保存字段更换为errorCode字段
     */
    @Deprecated
    public static LinkedResult Error(String code, String msg, Object data) {
        LinkedResult lr = new LinkedResult();
        lr.success = false;
        lr.code = code;
        lr.message = msg;
        lr.errorCode = LinkedCEM.ERROR_MESSAGE.getErrorCode();
        lr.data = data;
        return lr;
    }

    /**
     * @param msg 提示信息
     * @return 接口统一返回类
     * @Deprecated 针对参数错误的情况
     */
    public static LinkedResult CheckFailure(String msg) {
        LinkedResult lr = Complete(LinkedCEM.LACK_VALID_PARAM);
        lr.message = msg;
        return lr;
    }

    /**
     * @return true/false
     * @Deprecated 返回结果业务是否成功
     */
    public boolean ifSuccess() {
        return this.code.equals(LinkedCEM.SUCCESS.getCode()) && this.success;
    }

    /**
     * @return true/false
     * @Deprecated 返回结果业务是否失败
     */
    public boolean ifFailure() {
        return !this.success;
    }

    /**
     * @param cem 封装好的提示信息类
     * @return 接口统一返回类
     * @Deprecated 接口处理完成后，调用的方法
     */
    public static LinkedResult Complete(LinkedCEM cem) {
        LinkedResult lr = new LinkedResult();
        lr.setCode(cem.getCode().toString());
        lr.setMessage(cem.getMessage());
        lr.setSuccess(cem.isSuccess());
        lr.setErrorCode(cem.getErrorCode());
        return lr;
    }

    /**
     * @param cem  封装好的提示信息类
     * @param data 返回数据
     * @return 接口统一返回类
     * @Deprecated 完成方法
     */
    public static LinkedResult Complete(LinkedCEM cem, Object data) {
        LinkedResult lr = Complete(cem);
        lr.data = data;
        return lr;
    }

    /**
     * @return jons字符串或null
     * @throws JsonProcessingException json格式转化异常
     * @Deprecated 把data数据转化为json类型的字符串
     */
    public String jsonData() throws JsonProcessingException {
        if (this.data == null) {
            return null;
        }
        return OBJECT_MAPPER.writeValueAsString(this.data);
    }

}
